import { _decorator, Component, instantiate, Node, Prefab } from 'cc';
import { PREVIEW } from 'cc/env';

const { ccclass, property } = _decorator;

/**
 * 场景下使用的一些UI预制体挂载
 * 跟随场景销毁而销毁
 */
@ccclass('SceneUI')
export class SceneUI extends Component {

    // 单例组件
    private static _ins: SceneUI = null;

    // prefab 资源列表
    @property(Prefab)
    private readonly pfbList: Prefab[] = [];


    protected onLoad(): void {
        if (!SceneUI._ins)
            SceneUI._ins = this;
        else
            console.error("[SceneUI] 场景公用UI展示组件重复！");
    }

    protected onDestroy(): void {
        SceneUI._ins = null;
    }

    private static trimName(name: string): string {
        if (!name || !name.trim())
            PREVIEW && console.log("[SceneUI] 请求的UI名为空：", name);
        return name.trim();
    }

    private static getIns(): SceneUI {
        const ins = SceneUI._ins;
        if (!ins || !ins.isValid)
            PREVIEW && console.log("[SceneUI] 组件未初始化！");
        return ins;
    }

    /** 获取指定名称prefeb */
    static getPrefab(name: string): Prefab {
        name = this.trimName(name);
        if (!name) return null;
        const ins = this.getIns();
        if (!ins) return null;

        for (const pfb of ins.pfbList) {
            if (!!pfb && pfb.isValid && pfb.name == name)
                return pfb;
        }
        return null;
    }

    /** 获取场景公用的UI容器节点 -- 自身 */
    static get UiLayer(): Node {
        const ins = SceneUI._ins;
        if (!ins || !ins.isValid)
            return null;
        return ins.node;
    }

    /**
     * 显示指定UI
     * @param name UI名
     * @param exData.param 附带参数
     * @param exData.zIdx 层级
     * @returns 
     */
    static showLayer(name: string, exData?: { zIdx?: number, param?: any }): boolean {
        name = this.trimName(name);
        if (!name) return false;
        const ins = this.getIns();
        if (!ins) return false;

        let layer: Node = this.UiLayer.getChildByName(name);
        if (!layer) {
            const pfb = this.getPrefab(name);
            if (!pfb) {
                PREVIEW && console.log("[SceneUI] 暂不支持UI：", name);
                return false;
            }
            layer = instantiate(pfb);
            this.UiLayer.addChild(layer);
        }

        const comp: any = layer.getComponent("ComponentExt");
        if (!!comp && !!exData?.param) {
            comp.init(exData?.param);
        }
        layer.active = true;
        layer.setSiblingIndex(exData?.zIdx || 0);

        return true;
    }

    /**
     * 关闭指定UI
     * @param name UI名
     */
    static hideLayer(name: string) {
        name = this.trimName(name);
        if (!name) return;
        const ins = this.getIns();
        if (!ins) return;

        const layer: Node = this.UiLayer.getChildByName(name);
        if (!layer || !layer.active) return;

        const comp: any = layer.getComponent("ComponentExt");
        if (!!comp)
            comp.onClose();
        else
            layer.active = false;
    }

}

